import useStore from "../store";
import styles from "./style.module.less";
import { Expend } from "../icons";
import { TaskProps } from "../types";
import { Fragment, useEffect, useRef } from "react";

interface TasksProps {
  tasks: TaskProps[];
  onClick: (task: TaskProps) => void;
}

const RenderTree = (props: TasksProps): React.ReactElement => {
  const hoverId = useStore((state) => state.hoverId);
  const setHoverId = useStore((state) => state.setHoverId);
  const setExpendCount = useStore((state) => state.setExpendCount);
  return (
    <>
      {props.tasks.map((task) => {
        return (
          <Fragment key={task.id}>
            <div
              className={`${styles.item} ${
                task.id == hoverId ? styles.hover : ""
              }`}
              onMouseOver={() => {
                setHoverId(task.id);
              }}
              onMouseOut={() => {
                setHoverId("");
              }}
            >
              <div className={styles.itemName}>
                <div
                  className={styles.icon}
                  style={{ width: `${task.level * 20}px` }}
                  onClick={() => {
                    if (task.children && task.children.length > 0) {
                      setExpendCount();
                      props.onClick(task);
                    }
                  }}
                >
                  <div style={{ width: `${(task.level - 1) * 20}px` }}></div>
                  {task.children &&
                    task.children.length > 0 &&
                    (task.toggle ? (
                      <Expend
                        color={"#aaa"}
                        style={{ transform: "rotate(90deg)" }}
                      />
                    ) : (
                      <Expend color={"#aaa"} />
                    ))}
                </div>
                <div className={styles.name}>{task.name}</div>
              </div>
              <div>{task.startDate.format("YYYYMMDD")}</div>
              <div>{task.endDate.format("YYYYMMDD")}</div>
            </div>
            {task.children && task.children.length > 0 && task.toggle && (
              <RenderTree tasks={task.children} onClick={props.onClick} />
            )}
          </Fragment>
        );
      })}
    </>
  );
};

interface TaskListProps {
  height: number;
}

const TaskList = (props: TaskListProps) => {
  const tasks = useStore((state) => state.tasks);
  const setTasks = useStore((state) => state.setTasks);
  const scrollTop = useStore((state) => state.scrollTop);
  const setScrollTop = useStore((state) => state.setScrollTop);
  const taskListRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (taskListRef.current) {
      taskListRef.current.scrollTop = scrollTop;
    }
  }, [scrollTop]);

  const onClick = (taskParam: TaskProps) => {
    const updateTasks = (ts: TaskProps[], task: TaskProps) => {
      return ts.map((t) => {
        if (t.id === task.id) {
          if (t.children && t.children.length > 0) {
            t = { ...t, toggle: !t.toggle };
          }
        } else {
          if (t.children && t.children.length > 0) {
            t.children = updateTasks(t.children, task);
          }
        }
        return t;
      });
    };
    setTasks(updateTasks(tasks, taskParam));
  };

  return (
    <div className={styles.container} style={{ height: `${props.height}px` }}>
      <div className={styles.header}>
        <div className={styles.headerName}>Name</div>
        <div>Start</div>
        <div>End</div>
      </div>
      <div
        className={styles.items}
        ref={taskListRef}
        onWheel={(e) => {
          if (e.deltaMode !== 0) {
            const lineHeight = 16;
            e.deltaY = e.deltaY * lineHeight;
            e.deltaMode = 0;
          }
          const scrollAmount = Math.abs(e.deltaY) * 2;
          e.currentTarget.scrollTop +=
            e.deltaY > 0 ? scrollAmount : -scrollAmount;
          setScrollTop(e.currentTarget.scrollTop);
        }}
      >
        <RenderTree tasks={tasks} onClick={onClick} />
      </div>
    </div>
  );
};

export default TaskList;
